package cs3343.project.family.testing;

import static org.junit.Assert.*;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;

import org.junit.Test;

import cs3343.project.family.*;
import cs3343.project.family.Character;
import cs3343.project.family.UI.EventCardFrame;
import cs3343.project.family.UI.GameFrame;
import cs3343.project.family.UI.YesNoFrame;

/**
 * The Class RoleCardTest.
 */
public class RoleCardTest {
	
	/**
	 * The Class GameFrameStub.
	 */
	class GameFrameStub extends GameFrame{

		/**
		 * Instantiates a new game frame stub.
		 *
		 * @param w the w
		 * @param h the h
		 * @param gc the gc
		 */
		public GameFrameStub(int w, int h, GameController gc) {
			super(w, h, gc);
		}
		
		/* (non-Javadoc)
		 * @see cs3343.project.family.UI.GameFrame#setPlayerPanel()
		 */
		@Override
		public void setPlayerPanel() {
			
		}
		
	};
	
	/**
	 * The Class GameControllerStub.
	 */
	class GameControllerStub extends GameController {
		
		/**
		 * Instantiates a new game controller stub.
		 */
		public GameControllerStub() {
			super();
		}
		
		/* (non-Javadoc)
		 * @see cs3343.project.family.GameController#gameLost(int)
		 */
		@Override
		public boolean gameLost(int currentPlayer) {
			return false;
		}
		
		/* (non-Javadoc)
		 * @see cs3343.project.family.GameController#gameWon()
		 */
		@Override
		public boolean gameWon() {
			return false;
		}
	
	};
	
	/**
	 * The Class StatisticsControllerStub.
	 */
	class StatisticsControllerStub extends StatisticsController{

		/**
		 * Instantiates a new statistics controller stub.
		 *
		 * @param gc the gc
		 */
		public StatisticsControllerStub(GameController gc) {
			super(gc);	
			gc.setStatisticsController(this);
		}
		
		/* (non-Javadoc)
		 * @see cs3343.project.family.StatisticsController#addEsteemChange(int, int)
		 */
		@Override 
		public void addEsteemChange(int index, int esteem) {
			
		}
	
		/* (non-Javadoc)
		 * @see cs3343.project.family.StatisticsController#addplayerLog(int, java.lang.String)
		 */
		@Override 
		public void addplayerLog(int index, String event) {
			
		}
		
		/* (non-Javadoc)
		 * @see cs3343.project.family.StatisticsController#addplayerLog(cs3343.project.family.Character, java.lang.String)
		 */
		@Override
		public void addplayerLog(Character player, String event) {
			
		}		
	};
	
	/* Every 3 round, mumcounter+10.
	 * Case: after Round 13, mum's esteem become 0, esteem will be automatically add
	 * Result: At Round 14, mum's expected esteem : 40
	 * */
		
	// [GPA]	轉移能力	每兩回合可轉移自己100點自尊值予指定玩家
	/* Case : Gpa(500) transfer esteem to  Tester(150), 3 players
	 * Result: Gpa(400)  Tester(250)
	 * */
	/**
	 * Role mum.
	 */
	@Test
	public void roleMum() {
		
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
        ConfigManager.loadLangFile();
		GameControllerStub gc=new GameControllerStub();
		CharacterController cc=new CharacterController(gc);
		StatisticsControllerStub st=new StatisticsControllerStub(gc);
		gc.setCharacterController(cc);
		RoleController rolecontrol=new RoleController(gc);
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();
		
		//player setting 
        Character player = new Character("Player", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
		player.setEsteem(0);
		cc.addPlayer(player, 0);
		player.setRole(roles[0]);
		
		// mumcounter 
		gc.setMumCounter(40);
		gc.setRound(14);
		rolecontrol.mumRoleFunction();

		int result=player.getEsteem();
		assertEquals(result,40);
	}
	/* 
	 * Case: Dice is 3 , bro=currentPlayerIdx=0
	 * Result: bro cannot roll dice again, move to next player
	 * */
	/**
	 * Role bro1.
	 */
	@Test
	public void roleBro1() {
		class RoleControllerStub extends RoleController{
			public RoleControllerStub(GameController gc) {
				super(gc);
			}
			@Override
			public void passiveRoleFunction(){
			}
			@Override
			public void setRoleFunctionButtonText(){
			}
			
		};
		class DiceStub extends Dice{
			@Override
			public int rollDice(int high, int low) {
				return 3;
			}
		};
		
		//Player setting
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
       
        ConfigManager.loadLangFile();
		GameControllerStub gc=new GameControllerStub();
		CharacterController cc=new CharacterController(gc);
		gc.setCharacterController(cc);
		UIController ui=gc.getUiController();
		StatisticsControllerStub st=new StatisticsControllerStub(gc);
		gc.setStatisticsController(st);
		GameFrameStub gf=new GameFrameStub(200, 200, gc);
		ui.setGameFrame(gf);
		RoleControllerStub rolecontrol=new RoleControllerStub(gc);
		gc.setCharacterController(cc);
		gc.setRoleController(rolecontrol);
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();
		
		//player setting
		cc.setNumOfPlayer(3);
		for(int i=0;i<3;i++){
			Character player = new Character("Player", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
			player.setEsteem(0);
			cc.addPlayer(player, i);
		}
		gc.setCurrentPlayerIndex(0);
		cc.getPlayer(0).setRole(roles[1]);


		
		gc.setCurrentPlayerIndex(0);
		gc.afterPressed();
		
		int resultIdx=gc.getCurrentPlayerIndex();
		assertEquals(resultIdx,1);
		
	}
	
	/* 
	 * Case2: Dice is 6 , bro=currentPlayerIdx=2, noOfplayer=4
	 * Result: bro can roll dice again, wont move to next player
	 * */	
	/**
	 * Role bro2.
	 */
	@Test
	public void roleBro2() {
		class RoleControllerStub extends RoleController{
			public RoleControllerStub(GameController gc) {
				super(gc);
			}
			
			@Override
			public void passiveRoleFunction() {
				
			}
			
			@Override
			public void setRoleFunctionButtonText() {
				
			}			
		};
		// set roll dice return 6
		class DiceStub2 extends Dice{
			@Override
			public int rollDice(int high, int low) {
				return 6;
			}
		};
		
	
		int testerIdx=2;
		int numOfplayer=4;
		//Player setting
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
        ConfigManager.loadLangFile();
		GameControllerStub gc=new GameControllerStub();
		CharacterController cc= new CharacterController(gc);
		gc.setCharacterController(cc);
		StatisticsControllerStub st=new StatisticsControllerStub(gc);
		gc.setStatisticsController(st);		
		UIController ui= new UIController(gc);
		gc.setUiController(ui);
		RoleControllerStub rolecontrol=new RoleControllerStub(gc);
		gc.setRoleController(rolecontrol);
		GameFrameStub gf=new GameFrameStub(200, 200, gc);
		ui.setGameFrame(gf);
		gc.setDice(new DiceStub2());
		//Set player role to Bro
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();
		
		// player setting
		cc.setNumOfPlayer(4);
		for(int i=0;i<numOfplayer;i++){
			Character player = new Character("Player", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
			player.setEsteem(0);
			cc.addPlayer(player, i);
		}
		cc.getPlayer(testerIdx).setRole(roles[1]);

		
		gc.setCurrentPlayerIndex(testerIdx);
		gc.afterPressed();
		
		int resultIdx=gc.getCurrentPlayerIndex();
		assertEquals(resultIdx,testerIdx);
		
	}
	/*
	 * Case : in 6th round, dad having 500 esteem want to exchange tool card
	 * Result: 
	 * */
	/**
	 * Role dad.
	 */
	@Test
	public void roleDad() {
	
		class gameControllerStub2 extends GameController{
			@Override
			public boolean gameLost(int currentPlayer) {
				return false;
			}
			@Override
			public boolean gameWon() {
				return false;
			}
			@Override
			public void afterPressed() {}
		};
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
        ConfigManager.loadLangFile();
        gameControllerStub2 gc=new gameControllerStub2();
		CharacterController cc=gc.getCharacterController();
		StatisticsControllerStub st=new StatisticsControllerStub(gc);
		gc.setStatisticsController(st);
		CardController control=new CardController(gc);
		UIController ui=gc.getUiController();
		GameFrame gf=new GameFrame(0, 0, gc);
		ui.setGameFrame(gf);
		control.importToolCard();
		Card card=control.getMagicToolCard("2");
	
		RoleController rolecontrol=new RoleController(gc);
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();
		//player setting
		Character player = new Character("Player", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
		player.setEsteem(500);
		cc.addPlayer(player, 0);
		player.setRole(roles[2]);
		
		rolecontrol.applyCurrentRoleFunction();
		
		int result=player.getEsteem();
		assertEquals(result,450);
		
	}

	/**
	 * Role gpa.
	 */
	@Test
	public void roleGPA() {
	
		class gameControllerStub extends GameController{
			@Override
			public boolean gameLost(int currentPlayer) {
				return false;
			}
			@Override
			public boolean gameWon() {
				return false;
			}
			@Override
			public void afterPressed(){}
		};
		
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
        ConfigManager.loadLangFile();
        gameControllerStub gc=new gameControllerStub();
        CharacterController cc=gc.getCharacterController();
        StatisticsControllerStub st=new StatisticsControllerStub(gc);
        gc.setStatisticsController(st);
		RoleController rolecontrol=new RoleController(gc);
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();
		cc.setNumOfPlayer(3);
		
        Character player1 = new Character("GPA", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
		player1.setEsteem(500);
		cc.addPlayer(player1,0);
		player1.setRole(roles[3]);
		gc.setCurrentPlayerIndex(0);
		 
		// set role to sis
	    Character player2 = new Character("Sis", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
		player2.setEsteem(0);
		cc.addPlayer(player2,1);
		player2.setRole(roles[4]);
		
		// set role to Tester
	    Character player3 = new Character("Tester", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
	    player3.setEsteem(150);
		cc.addPlayer(player3,2);
		player3.setRole(roles[0]);
		
		
		rolecontrol.applyCurrentRoleFunction();
		int gpaEsteem=player1.getEsteem();
		int testerEsteem=player3.getEsteem();
		
		assertEquals(gpaEsteem,400);
		assertEquals(testerEsteem,250);
		
	}
	
	// Case: in Round 3, if player give up oral task, esteem point remain unchanged
	/**
	 * Role gma.
	 */
	@Test
	public void roleGMA() {
		class gameControllerStub extends GameController{
			@Override
			public boolean gameLost(int currentPlayer) {
				return false;
			}
			@Override
			public boolean gameWon() {
				return false;
			}
			@Override
			public void afterPressed(){}
		};
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
        ConfigManager.loadLangFile();
        gameControllerStub gc=new gameControllerStub();
		CharacterController cc=gc.getCharacterController();
		StatisticsControllerStub st=new StatisticsControllerStub(gc);
		gc.setStatisticsController(st);
		CardController control=new CardController(gc);
		gc.setCardController(control);
		UIController ui=gc.getUiController();
		GameFrame gf=new GameFrame(0, 0, gc);
		ui.setGameFrame(gf);
		gc.setRound(6);

	
		RoleController rolecontrol=new RoleController(gc);
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();
		//player setting 
		Character player = new Character("Player", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
		player.setEsteem(250);
		cc.addPlayer(player, 0);
		player.setRole(roles[4]);
		gc.setCurrentPlayerIndex(0);
		gc.setOriSE(player.getEsteem());                              

		// oral card frame
		control.importOralCard();
		Card oralCard=control.getOralCard(String.valueOf(2));
		YesNoFrame oralF=new YesNoFrame(cc.getPlayer(0),oralCard,"OralCard",gc);
	
		JButton giveup=oralF.getBtn_giveup();
		giveup.doClick();
		gc.setNewSE(player.getEsteem());
	
		// check if skip penalty
		rolecontrol.passiveRoleFunction();
		int gmaEsteem=player.getEsteem();
		assertEquals(gmaEsteem,250);
		
	}
	

	/**
	 * Role si s_no tool.
	 */
	@Test
	public void roleSIS_noTool() {
		class gameControllerStub extends GameController{
			@Override
			public boolean gameLost(int currentPlayer) {
				return false;
			}
			@Override
			public boolean gameWon() {
				return false;
			}
			@Override
			public void afterPressed(){}
		};
		class StatisticsControllerStub3 extends StatisticsController{

			public StatisticsControllerStub3(GameController gc) {
				super(gc);	
				gc.setStatisticsController(this);
			}

			@Override
			public void addplayerLog(Character player, String event){}
			
		};
		String proimgPath = ConfigManager.IMAGE_PATH + "profilePic1" + ".jpg";
        String iconimgPath = ConfigManager.IMAGE_PATH + "char1" + ".jpg";
        String gproimgPath = ConfigManager.IMAGE_PATH + "gprofilePic1" + ".jpg";
        
        ConfigManager.loadLangFile();
        gameControllerStub gc=new gameControllerStub();
		CharacterController cc=new CharacterController(gc);
		gc.setCharacterController(cc);
		cc.setNumOfPlayer(1);
		StatisticsControllerStub3 st=new StatisticsControllerStub3(gc);
		gc.setStatisticsController(st);
		CardController control=new CardController(gc);
		gc.setCardController(control);
		UIController ui=new UIController(gc);
		gc.setUiController(ui);
		RoleController rolecontrol=new RoleController(gc);
		gc.setRoleController(rolecontrol);				
		rolecontrol.importRole();
		Role[] roles=rolecontrol.getAllRoles();		
		st.initPlayerGameLog(cc.getNumOfPlayer());
		
		//player setting 
		Character player = new Character("Player", new ImageIcon(proimgPath),new ImageIcon(gproimgPath), new ImageIcon(iconimgPath));
		player.setEsteem(850);
		cc.addPlayer(player, 0);
		player.setRole(roles[5]);
		gc.setCurrentPlayerIndex(0);
		gc.setOriSE(player.getEsteem());                              

		GameFrame gf=new GameFrame(0, 0, gc);
		ui.setGameFrame(gf);
		gc.setRound(6);
		
		// oral card frame
		control.importOralCard();
		Card oralCard=control.getOralCard(String.valueOf(2));
		YesNoFrame oralF=new YesNoFrame(cc.getPlayer(0),oralCard,"OralCard",gc);
		
	
		gc.setNewSE(900);						// esteem after click done
		JButton done=oralF.getBtn_okay();
		done.doClick();
	
		int sisEsteem=player.getEsteem();
		assertEquals(sisEsteem,910);	
		
		
	}

}
